#include "led_op.h"
#include <FreeRTOS.h>
#include <task.h>
#include "io_out.h"

static uint8_t led_status = 0x0f;

static void led_task(void *args)
{
    int on_time, off_time;

    /* Start: for breath light */
    int count_flag = 1;
    int cycle = 20;
    int high_time = 0;
    /* End: for breath light */

    while (1) {
        led_status_t stat = 0;

        while (stat < LED_STAT_OK) {
            if (led_status & (1 << stat)) {
                break;
            }
            stat++;
        }

        switch (stat) {
            case LED_STAT_NOT_CONFIG: {
                on_time = 2000;
                off_time = 0;
            } break;
            case LED_STAT_NO_NETWORK: {
                on_time = 1900;
                off_time = 100;
            } break;
            case LED_STAT_INVALID_TIME: {
                on_time = 100;
                off_time = 1900;
            } break;
            case LED_STAT_SENSOR_FAULT: {
                on_time = 100;
                off_time = 200;
            } break;
            case LED_STAT_BREATH: {
                high_time += count_flag;
                if ((high_time >= cycle) || (high_time <= 0)) {
                    count_flag = -count_flag;
                }
                on_time = high_time;
                off_time = cycle - high_time;
            } break;
            case LED_STAT_OK: {
                on_time = 10;
                off_time = 2990;
            } break;
            default: {
                on_time = 10;
                off_time = 1990;
            } break;
        }

        io_out(LED, 1);
        vTaskDelay(on_time);
        io_out(LED, 0);
        vTaskDelay(off_time);
    }
}

void init_led(void)
{
    xTaskCreate(led_task, (char *)"LED task", 128, NULL, 20, NULL);
}

void led_set_status(led_status_t status)
{
    if (status == LED_STAT_OK) {
        led_status = 0x00;
    } else {
        led_status |= 1 << status;
    }
}

void led_clear_status(led_status_t status)
{
    if (status == LED_STAT_OK) {
        led_status = 0x0f;
    } else {
        led_status &= ~(1 << status);
    }
}

led_status_t led_get_status(void)
{
    return led_status;
}

int is_set_led_stat(led_status_t status)
{
    return !!(led_status & (1 << status));
}
